local FightManager = class("FightManager")
local GameUtils = require("utils.GameUtils")
local Vector3 = require("utils.Vector3")
local AutoEntity = require("gameLogic.fightEntity.AutoEntity")
local FightConst = require("const.FightConst")
local BuildHelper = require("gameLogic.fight.BuildHelper")
local BuffManager = require("gameLogic.buff.BuffManager")

local ENTITY_POS = {0, 3, -3}
local ENTITY_POS_Z = {0, 3}

local FRIEND_ACTORS = {
    {1, 2, 5},
    {7, 8, 9}
}
local ENEMY_ACTORS = {
    {3, 16, 6},
    {10}
}

function FightManager:ctor()
    self._buffManager = BuffManager.new()
end

function FightManager:start()
    self._friendEntitys = {}
    self._enemyEntitys = {}
    self._entitys = {} -- 未行动列表
    self._doneEntitys = {} -- 已经行动列表
    self._delayStart = 1 -- 延迟开始战斗
    self._isPause = false
    self._fightUI = G_UIManager:openFixUI("FightUI")
    self._fightUI:setManager(self)
    self:_initMonsterTeamId()
    self:_initFriends()
    self:_initEnemys()
    self._round = 1 -- 回合数
    self._bloodFag = false
    self._fightUI:setRoundText(string.format(Lang.get("round_text"), self._round))
    self:_sortEntitys()
    self:_initListener()
end

function FightManager:getFightUI()
    return self._fightUI
end

function FightManager:_initMonsterTeamId()
    local monsterId = G_UserData:getGameCache():getFight_monster_id()
    local monsCfg = require("config.monster_team").get(monsterId)
    assert(monsCfg, "can not found config in monster_team by id=" .. monsterId)
    local row1 = {}
    local row2 = {}
    for i = 1, 3 do
        if monsCfg["monster_" .. i] > 0 then
            table.insert(row1, monsCfg["monster_" .. i])
        end
    end
    for i = 4, 6 do
        if monsCfg["monster_" .. i] > 0 then
            table.insert(row2, monsCfg["monster_" .. i])
        end
    end
    ENEMY_ACTORS = {}
    table.insert(ENEMY_ACTORS, row1)
    table.insert(ENEMY_ACTORS, row2)
    dump(ENEMY_ACTORS)
end

function FightManager:setPause(pause)
    self._isPause = pause
end

function FightManager:getBuffManager()
    return self._buffManager
end

function FightManager:_initListener()
    self._siganlEntityDie =
        G_SignalManager:add(SignalConst.EVENT_FIGHT_ENTITY_DIE, handler(self, self._onEvenEntityDie))
end

function FightManager:_sortEntitys()
    table.sort(
        self._entitys,
        function(a, b)
            local AttributeConst = require("const.AttributeConst")
            local speeda = a:getAttr():getAttrValue(AttributeConst.SPEED)
            local speedb = b:getAttr():getAttrValue(AttributeConst.SPEED)
            return speeda > speedb
        end
    )
end

function FightManager:_initFriends()
    for i = 1, #FRIEND_ACTORS do
        for j = 1, #FRIEND_ACTORS[i] do
            local gameObject = nil
            local luaBehaviour = nil
            if FRIEND_ACTORS[i][j] == 1 then
                gameObject, luaBehaviour = BuildHelper.buildUser(FRIEND_ACTORS[i][j], self, FightConst.FRIEND_STANDING)
            else
                gameObject, luaBehaviour =
                    BuildHelper.buildMonster(FRIEND_ACTORS[i][j], self, FightConst.FRIEND_STANDING)
            end
            GameUtils.addChildTo(self.FriendPoint.transform, gameObject.transform)
            gameObject.transform.localPosition = Vector3.new(ENTITY_POS[j], 0, ENTITY_POS_Z[i])
            local luaScriptEnv = luaBehaviour:GetScriptEnv()
            luaScriptEnv:setStance(i, j)
            table.insert(self._friendEntitys, luaScriptEnv)
            table.insert(self._entitys, luaScriptEnv)
        end
    end
end

function FightManager:_initEnemys()
    for i = 1, #ENEMY_ACTORS do
        for j = 1, #ENEMY_ACTORS[i] do
            local gameObject, luaBehaviour =
                BuildHelper.buildMonster(ENEMY_ACTORS[i][j], self, FightConst.ENEMY_STANDING)
            GameUtils.addChildTo(self.EnenyPoint.transform, gameObject.transform)
            gameObject.transform.localPosition = Vector3.new(-ENTITY_POS[j], 0, ENTITY_POS_Z[i])
            gameObject.transform.localEulerAngles = Vector3.new(0, 0, 0)
            local luaScriptEnv = luaBehaviour:GetScriptEnv()
            luaScriptEnv:setStance(i, j)
            table.insert(self._enemyEntitys, luaScriptEnv)
            table.insert(self._entitys, luaScriptEnv)
        end
    end
end

function FightManager:update()
    if self:_needLoop() then
        self:_fightLoop()
    end
    if not self._bloodFag then
        self._bloodFag = true
        self._fightUI:initEntityBloodUI(self._entitys)
    end
end

function FightManager:_needLoop()
    if #self._enemyEntitys == 0 or #self._friendEntitys == 0 then -- 没人
        return false
    end
    if self:_isAllDie(self._friendEntitys) or self:_isAllDie(self._enemyEntitys) then -- 战斗结束
        return false
    end
    if self._delayStart > 0 then -- 等几秒再开战
        self._delayStart = self._delayStart - G_Time.deltaTime
        return false
    end
    if self._isPause then
        return false
    end
    return true
end

-- 战斗循环
function FightManager:_fightLoop()
    self:_entityAction()
    self:_checkGoNextEntity()
    self:_checkGoNextRound()
end

function FightManager:_entityAction()
    local curEntity = self._entitys[1]
    if self._lastEntity ~= curEntity then
        G_SignalManager:dispatch(SignalConst.EVENT_ACTION_BEGIN_BUFF, FightConst.BUFF_ACTION_BEGIN, curEntity)
    end
    curEntity:tick()
    self._lastEntity = curEntity
end

function FightManager:_checkGoNextEntity()
    local curEntity = self._entitys[1]
    if curEntity:isDone() then
        table.remove(self._entitys, 1)
        table.insert(self._doneEntitys, curEntity)
        G_SignalManager:dispatch(SignalConst.EVENT_ACTION_END_BUFF, FightConst.BUFF_ACTION_END, curEntity)
    end
end

function FightManager:_checkGoNextRound()
    if #self._entitys == 0 then
        self:_addRound()
        self:_resetEntity()
    end
end

function FightManager:_addRound()
    self._round = self._round + 1
    self._fightUI:setRoundText(string.format(Lang.get("round_text"), self._round))
    G_SignalManager:dispatch(SignalConst.EVENT_ROUND_END_BUFF, FightConst.BUFF_ROUND)
end

function FightManager:_resetEntity()
    for i, entity in pairs(self._doneEntitys) do
        entity:reset()
        table.insert(self._entitys, entity)
    end
    self._doneEntitys = {}
    self._lastEntity = nil
end

-- 获取敌人栗色表
function FightManager:getEnemyEntitys(target)
    local result = {}
    local findList = {}
    if target == FightConst.ENEMY_STANDING then
        findList = self._friendEntitys
    else
        findList = self._enemyEntitys
    end
    for i, entity in ipairs(findList) do
        if not entity:isDie() then
            table.insert(result, entity)
        end
    end
    return result
end

function FightManager:getEnemyEntityCenterPos(target)
    if target == FightConst.ENEMY_STANDING then
        return self.FriendPoint.transform.position
    else
        return self.EnenyPoint.transform.position
    end
end

function FightManager:getEnemyEntityPointTransform(target)
    if target == FightConst.ENEMY_STANDING then
        return self.FriendPoint.transform
    else
        return self.EnenyPoint.transform
    end
end

function FightManager:_onEvenEntityDie(id)
    self:_checkFightEnd()
end

function FightManager:_checkFightEnd()
    if self._isEnd then
        return
    end
    if self:_isAllDie(self._friendEntitys) then
        self:_setEnd(Lang.get("fight_lose_tip"))
        return
    end
    if self:_isAllDie(self._enemyEntitys) then
        self:_setEnd(Lang.get("fight_win_tip"))
        return
    end
end

function FightManager:_setEnd(text)
    local PopupFightEnd = require("view.popup.PopupFightEnd")
    local popup = PopupFightEnd:create()
    popup:setTip(text)
    self._isEnd = true
end

function FightManager:_isAllDie(entitys)
    local dieCount = 0
    for i = 1, #entitys do
        if entitys[i]:isDie() then
            dieCount = dieCount + 1
        end
    end
    if dieCount == #entitys then
        return true
    end
    return false
end

function FightManager:isFightEnd()
    return self._isEnd
end

function FightManager:onDestroy()
    G_Time.timeScale = 1 -- 还原时间
    self._fightUI:close()
    self._buffManager:destroy()
    self._siganlEntityDie:remove()
    self._siganlEntityDie = nil
end

return FightManager
